package ipebg.mzk.common.util;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.PrintStream;
import java.io.RandomAccessFile;
import java.io.UnsupportedEncodingException;
import java.net.URL;
import java.net.URLConnection;
import java.nio.ByteBuffer;
import java.nio.CharBuffer;
import java.nio.MappedByteBuffer;
import java.nio.channels.FileChannel;
import java.nio.charset.Charset;
import java.nio.charset.CharsetDecoder;
import java.util.ArrayList;
import java.util.List;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.http.util.ByteArrayBuffer;

/**
 * 
 * @author xiao-qiao.liu
 *
 */
public class FileUtil {

	private static Log log = LogFactory.getLog(FileUtil.class);

	public int getFileLength(String path) {
		File file = new File(path);
		return (int) file.length();
	}

	/**
	 * 
	 * @param path
	 * @param indexStar
	 * @param length
	 * @return
	 * @throws IOException
	 */
	public byte[] RandomReadFile(String path, int indexStar, int length) throws IOException {
		byte[] bs1 = new byte[length];
		try {
			File file = new File(path);
			RandomAccessFile fileAccess = new RandomAccessFile(file, "r");
			fileAccess.seek(indexStar);// 将文件指针指向開始

			fileAccess.read(bs1);

		} catch (Exception e) {
			e.printStackTrace();
		}
		return bs1;
	}

	
	/**
	 * 获得指定文件的byte数组
	 * @param filePath
	 * @return
	 */
	public static byte[] getBytesFromFilePath(String filePath){
		byte[] buffer = null;
		try {
			File file = new File(filePath);
			FileInputStream fis = new FileInputStream(file);
			ByteArrayOutputStream bos = new ByteArrayOutputStream(1000);
			byte[] b = new byte[1000];
			int n;
			while ((n = fis.read(b)) != -1) {
				bos.write(b, 0, n);
			}
			fis.close();
			bos.close();
			buffer = bos.toByteArray();
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
		return buffer;
	}
	
	
	/**
	 * 根据byte数组，生成文件
	 * @param bfile
	 * @param filePath
	 * @param fileName
	 */
	public static void writeFileFromBytes(byte[] bfile, String filePath,String fileName) {
		BufferedOutputStream bos = null;
		FileOutputStream fos = null;
		File file = null;
		try {
			File dir = new File(filePath);
			if(!dir.exists()&&dir.isDirectory()){//判断文件目录是否存在
				dir.mkdirs();
			}
			file = new File(filePath+"\\"+fileName);
			fos = new FileOutputStream(file);
			bos = new BufferedOutputStream(fos);
			bos.write(bfile);
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			if (bos != null) {
				try {
					bos.close();
				} catch (IOException e1) {
					e1.printStackTrace();
				}
			}
			if (fos != null) {
				try {
					fos.close();
				} catch (IOException e1) {
					e1.printStackTrace();
				}
			}
		}
	}

	
	
	
	/**
	 * 獲取指定文件目錄下特定扩展名的文件
	 * 
	 * @param path
	 *            文件夾咱徑
	 * @param format
	 *            文件格式(三位文件擴展名)
	 * @return 文件中的有文件清單
	 */
	public List<File> GetFolderBitmap(String path, String format) {
		List<File> resultFiles = new ArrayList<File>();
		File folder = new File(path);
		File[] files = folder.listFiles();
		String extFilename;
		for (int i = 0; i < files.length; i++) {
			File file = files[i];
			extFilename = file.getPath().substring(file.getPath().length() - 3, file.getPath().length());
			if (extFilename.equalsIgnoreCase(format)) {
				resultFiles.add(file);
			}
		}
		return resultFiles;
	}

	/**
	 * 判断文件是否存在
	 * 
	 * @param filePath
	 * @return 存在返回true,不存在返回false
	 */
	public static boolean ValidateFileExisted(String filePath) {
		File file = new File(filePath);
		return (file.exists()) ? true : false;
	}

	/**
	 * 以特點碼方式讀取全部文件
	 * 
	 * @param path
	 *            讀取的文件咱徑
	 * @param EncodeType
	 *            "UTF-8"等
	 * @return
	 * @throws UnsupportedEncodingException
	 * @throws FileNotFoundException
	 */
	public char[] ReadFile(String path, String EncodeType) throws UnsupportedEncodingException, FileNotFoundException {
		FileInputStream is = new FileInputStream(path);
		InputStreamReader isr = new InputStreamReader(is, EncodeType);
		BufferedReader br = new BufferedReader(isr);

		char buffer[] = null;
		try {
			buffer = new char[is.available()];
			System.out.println("buffer length=" + buffer.length);
		} catch (IOException e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();
		}
		try {
			br.read(buffer);
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			try {
				if (br != null) {
					br.close();
				}
			} catch (IOException e) {
				e.printStackTrace();
				;
			}
		}
		return buffer;
	}

	/**
	 * 以UTF-8編碼方式讀取全部文件
	 * 
	 * @param:path : 路徑 方法已OK
	 * */
	public char[] ReadUTF8File(String path) throws FileNotFoundException, UnsupportedEncodingException {

		FileInputStream is = new FileInputStream(path);
		InputStreamReader isr = new InputStreamReader(is, "UTF-8");
		BufferedReader br = new BufferedReader(isr);

		char buffer[] = null;
		try {
			buffer = new char[is.available()];
			System.out.println("buffer length=" + buffer.length);
		} catch (IOException e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();
		}
		try {
			br.read(buffer);
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			try {
				if (br != null) {
					br.close();
				}
			} catch (IOException e) {
				e.printStackTrace();
				;
			}
		}
		return buffer;
	}

	/**
	 * 用UTF-8編碼方式，從文件頭讀取特定長度文件
	 * 
	 * @param:path : 路徑
	 * @param:length:讀取文件的長度,從0開始 方法已OK
	 * */
	public char[] ReadUTF8File(String path, int length) throws FileNotFoundException, UnsupportedEncodingException {

		FileInputStream is = new FileInputStream(path);
		InputStreamReader isr = new InputStreamReader(is, "UTF-8");
		BufferedReader br = new BufferedReader(isr);

		char buffer[] = new char[length];

		try {
			br.read(buffer);

		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			try {
				if (br != null) {
					br.close();
				}
			} catch (IOException e) {
				e.printStackTrace();
				;
			}
		}
		return buffer;
	}

	/**
	 * 用UTF-8編碼方式，從文件特定位置讀取特定長度文件
	 * 
	 * @param:path : 路徑
	 * @param:length:讀取文件的長度
	 * @param:indesStar:開始位置 方法已OK
	 * */
	public char[] ReadUTF8File(String path, int indexStar, int length) throws FileNotFoundException, UnsupportedEncodingException {
		FileInputStream is = new FileInputStream(path);
		InputStreamReader isr = new InputStreamReader(is, "UTF-8");
		BufferedReader br = new BufferedReader(isr);
		char buffer[] = new char[length];
		try {
			br.read(buffer, indexStar, 512);
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			try {
				if (br != null) {
					br.close();
				}
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		return buffer;
	}

	/**
	 * 用特定編碼方式，從文件特定位置讀取特定長度文件
	 * 
	 * @param path
	 * @param indexStar
	 * @param length
	 * @param EncodeType
	 * @return
	 * @throws FileNotFoundException
	 * @throws UnsupportedEncodingException
	 */
	public char[] ReadFile(String path, int indexStar, int length, String EncodeType) throws FileNotFoundException, UnsupportedEncodingException {
		FileInputStream is = new FileInputStream(path);
		InputStreamReader isr = new InputStreamReader(is, "UTF-8");
		BufferedReader br = new BufferedReader(isr);
		char buffer[] = new char[length];
		try {
			br.read(buffer, indexStar, 512);
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			try {
				if (br != null) {
					br.close();
				}
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		return buffer;
	}

	/**
	 * 從網上下載文件到本地
	 * 
	 * @param uri
	 *            地址
	 * @param savePath
	 *            本地路徑
	 * @return
	 */
	public boolean ReadURLFile(URL uri, String savePath) {
		File file;
		FileOutputStream out;
		try {
			URLConnection ucon = uri.openConnection();
			InputStream is = ucon.getInputStream();
			BufferedInputStream bis = new BufferedInputStream(is);
			ByteArrayBuffer baf = new ByteArrayBuffer(100);
			int current = 0;

			while ((current = bis.read()) != -1) {
				baf.append((byte) current);
			}

			file = new File(savePath);
			file.createNewFile();
			out = new FileOutputStream(file);
			out.write(baf.toByteArray());
			out.close();

			return true;
		} catch (IOException e) {
			e.printStackTrace();
			return false;
		}
	}


	/**
	 * 随机读取UTF-8文件内容
	 */
	public char[] readFileByRandomAccess(String filePath, int start, int len) {
		RandomAccessFile randomFile = null;
		CharBuffer cb = null;
		try {
			// System.out.println("随机读取一段文件内容：");
			// 打开一个随机访问文件流，按只读方式
			randomFile = new RandomAccessFile(filePath, "r");

			// 读文件的起始位置
			int beginIndex = start;// (fileLength > 4) ? 4 : 0;
			// 将读文件的开始位置移到beginIndex位置。
			randomFile.seek(beginIndex);

			byte[] bytes = new byte[len];
			int byteread = 0;
			// 一次读10个字节，如果文件内容不足10个字节，则读剩下的字节。
			// 将一次读取的字节数赋给byteread

			randomFile.read(bytes);

			Byte a = bytes[4999];

			// String temp = new String(bytes,"UTF-8");
			// System.out.print(temp);

			Charset cs = Charset.forName("UTF-8");
			// Charset cs = Charset.forName (" UTF-16LE");
			ByteBuffer bb = ByteBuffer.allocate(bytes.length);
			bb.put(bytes);
			bb.flip();

			cb = cs.decode(bb);

			/*
			 * 若要讀到文件結束 while ((byteread = randomFile.read(bytes)) != -1) {
			 * String temp = new String(bytes,"UTF-8"); System.out.print(temp);
			 * }
			 */
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			if (randomFile != null) {
				try {
					randomFile.close();
				} catch (IOException e1) {
				}
			}
		}
		return cb.array();
	}

	/**
	 * 在一個文件中返回特定字符串的索引位置
	 * 
	 * @param filePath
	 *            文件路徑
	 * @param strObj
	 *            被查找的字符串
	 * @return 返回索引位置，沒找到返回負數
	 */
	public int SearchStringFromFile(String filePath, String strObj) {
		int n = -1;
		Charset charset = Charset.forName("UTF-8");
		CharsetDecoder decoder = charset.newDecoder();
		try {
			FileInputStream fis = new FileInputStream(filePath);
			FileChannel fc = fis.getChannel();

			int sz = (int) fc.size();
			MappedByteBuffer bb = fc.map(FileChannel.MapMode.READ_ONLY, 0, sz);
			CharBuffer cb = decoder.decode(bb);
			String s = String.valueOf(cb);
			n = s.indexOf(strObj);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return n;
	}

	/**
	 * writefile
	 * 
	 * @param str
	 * @param path
	 */
	public void writeFile(byte[] str, String path) {
		File file;

		FileOutputStream out;
		try {
			file = new File(path);
			file.createNewFile();

			out = new FileOutputStream(file);
			out.write(str);
			out.close();
		} catch (IOException e) {
			e.printStackTrace();
			log.error("writefile " + path + " error = " + e.getMessage());
		}
	}

	/** */
	/**
	 * 以文件流的方式复制文件
	 * 
	 * @param src
	 *            文件源目录
	 * @param dest
	 *            文件目的目录
	 * @throws IOException
	 */
	public void copyFile(String src, String dest) throws IOException {
		FileInputStream in = new FileInputStream(src);
		File file = new File(dest);
		if (!file.exists())
			file.createNewFile();
		FileOutputStream out = new FileOutputStream(file);
		int c;
		byte buffer[] = new byte[1024];
		while ((c = in.read(buffer)) != -1) {
			for (int i = 0; i < c; i++)
				out.write(buffer[i]);
		}
		in.close();
		out.close();
	}

	// 1.利用PrintStream写文件
	// 文件输出示例
	public void PrintStreamDemo(String filePath) {
		try {
			FileOutputStream out = new FileOutputStream(filePath);
			PrintStream p = new PrintStream(out);
			for (int i = 0; i < 10; i++)
				p.println("This is " + i + " line");
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		}
	}

	// 利用StringBuffer写文件
	// 该方法可以设定使用何种编码，有效解决中文问题。
	public void WriteStringBuffer(String filePath, String str) throws IOException {
		File file = new File(filePath);// /root/sms.log
		if (!file.exists())
			file.createNewFile();
		FileOutputStream out = new FileOutputStream(file, true);
		for (int i = 0; i < 10000; i++) {
			StringBuffer sb = new StringBuffer();
			sb.append(str);
			out.write(sb.toString().getBytes("utf-8"));
		}
		out.close();
	}

	/** */
	/**
	 * 文件重命名
	 * 
	 * @param path
	 *            文件目录
	 * @param oldname
	 *            原来的文件名
	 * @param newname
	 *            新文件名
	 */
	public void renameFile(String path, String oldname, String newname) {
		if (!oldname.equals(newname)) {// 新的文件名和以前文件名不同时,才有必要进行重命名
			File oldfile = new File(path + "/" + oldname);
			File newfile = new File(path + "/" + newname);
			if (newfile.exists())// 若在该目录下已经有一个文件和新文件名相同，则不允许重命名
				System.out.println(newname + "已经存在！");
			else {
				oldfile.renameTo(newfile);
			}
		}
	}

	// 转移文件目录不等同于复制文件，复制文件是复制后两个目录都存在该文件，而转移文件目录则是转移后，只有新目录中存在该文件。
	/** */
	/**
	 * 转移文件目录
	 * 
	 * @param filename
	 *            文件名
	 * @param oldpath
	 *            旧目录
	 * @param newpath
	 *            新目录
	 * @param cover
	 *            若新目录下存在和转移文件具有相同文件名的文件时，是否覆盖新目录下文件，cover=true将会覆盖原文件，否则不操作
	 */
	public void changeDirectory(String filename, String oldpath, String newpath, boolean cover) {
		if (!oldpath.equals(newpath)) {
			File oldfile = new File(oldpath + "/" + filename);
			File newfile = new File(newpath + "/" + filename);
			if (newfile.exists()) {// 若在待转移目录下，已经存在待转移文件
				if (cover)// 覆盖
					oldfile.renameTo(newfile);
				else
					System.out.println("在新目录下已经存在：" + filename);
			} else {
				oldfile.renameTo(newfile);
			}
		}
	}

	/** */
	/**
	 * 删除文件
	 * 
	 * @param path
	 *            目录
	 * @param filename
	 *            文件名
	 */
	public void delFile(String path, String filename) {
		File file = new File(path + "/" + filename);
		if (file.exists() && file.isFile())
			file.delete();
	}

	// 删除目录
	// 要利用File类的delete()方法删除目录时，必须保证该目录下没有文件或者子目录，否则删除失败，因此在实际应用中，我们要删除目录，必须利用递归删除该目录下的所有子目录和文件，然后再删除该目录。

	/** */
	/**
	 * 递归删除文件夹
	 * 
	 * @param path
	 */
	public void delDir(String path) {
		File dir = new File(path);
		if (dir.exists()) {
			File[] tmp = dir.listFiles();
			for (int i = 0; i < tmp.length; i++) {
				if (tmp[i].isDirectory()) {
					delDir(path + "/" + tmp[i].getName());
				} else {
					tmp[i].delete();
				}
			}
			dir.delete();
		}
	}

	// 读文件
	/** */
	/**
	 * 读文件
	 * 
	 * @param path
	 * @return
	 * @throws IOException
	 */
	public String BufferedReader(String path) throws IOException {
		File file = new File(path);
		if (!file.exists() || file.isDirectory())
			throw new FileNotFoundException();
		BufferedReader br = new BufferedReader(new FileReader(file));
		String temp = null;
		StringBuffer sb = new StringBuffer();
		temp = br.readLine();
		while (temp != null) {
			sb.append(temp + " ");
			temp = br.readLine();
		}
		return sb.toString();
	}

	/** */
	/**
	 * 读文件
	 * 
	 * @param path
	 * @return
	 * @throws IOException
	 */
	public String FileInputStream(String path) throws IOException {
		File file = new File(path);
		if (!file.exists() || file.isDirectory())
			throw new FileNotFoundException();
		FileInputStream fis = new FileInputStream(file);
		byte[] buf = new byte[1024];
		StringBuffer sb = new StringBuffer();
		while ((fis.read(buf)) != -1) {
			sb.append(new String(buf));
			buf = new byte[1024];// 重新生成，避免和上次读取的数据重复
		}
		return sb.toString();
	}

	
	/**
	 * 創建文件夾 方法 OK
	 * 
	 * @param folderPath
	 * @return
	 * @throws Exception
	 */
	public static boolean CreateFolder(String folderPath) {
		Boolean bResult = false;
		try {
			File f = new File(folderPath);
			if (!f.exists()) {
				bResult = f.mkdir();
			}
			return bResult;
		} catch (Exception err) {
			err.printStackTrace();
		}
		return bResult;
	}

	public boolean DeleteFolder(String folderPath) throws Exception {
		Boolean bResult = false;
		try {
			File f = new File(folderPath);
			if (f.exists()) {
				bResult = f.delete();
			}
			return bResult;
		} catch (Exception err) {
			throw err;
		}
	}


	private static final String FILE_PATH="C:\\Users\\Administrator\\Downloads\\OMSAIPE_VAL.bpmn20.xml";
	public static void main(String[] args){
		byte[] bytes=FileUtil.getBytesFromFilePath(FILE_PATH);
		System.out.print(new String(bytes));
	}
}
